#include "MSPIX.h"


static S_Pix g_p_s_pix[MAX_S_PIX_NUM];

static unsigned char  g_p_src_img  [IMG_MAX_SIZE * 3 * IMG_MAX_SIZE];
static unsigned char  g_p_af_map   [IMG_MAX_SIZE * 3 * IMG_MAX_SIZE];
static short          g_p_s_pix_map[IMG_MAX_SIZE * 3 * IMG_MAX_SIZE];

static unsigned char  g_p_edge_map [IMG_MAX_SIZE * 3 * IMG_MAX_SIZE];
static unsigned char  g_p_seg_map  [IMG_MAX_SIZE * 3 * IMG_MAX_SIZE];
static unsigned char  g_p_debug_img[IMG_MAX_SIZE * 3 * IMG_MAX_SIZE];

int g_neighbor_matrix[S_PIX_NUM][S_PIX_NUM];


unsigned char g_spix_debug_map[IMG_MAX_SIZE * 3 * IMG_MAX_SIZE];


void init_mspix(unsigned char* p_src_img, unsigned char* p_af_map, int width, int height, MSPIX_API* p_spix_api, int layer_id)
{
	int i = 0, x = 0, y = 0;
	int index = 0;
	p_spix_api->p_spix        = g_p_s_pix;
	p_spix_api->p_src_img     = g_p_src_img;
	p_spix_api->p_s_pix_map   = g_p_s_pix_map;
	p_spix_api->p_edge_map    = g_p_edge_map;
	p_spix_api->p_seg_map     = g_p_seg_map;
	p_spix_api->p_debug_img   = g_p_debug_img;
	p_spix_api->p_af_map      = g_p_af_map;

	p_spix_api->layer_id      = layer_id;
	p_spix_api->img_width     = width;
	p_spix_api->img_height    = height;
	p_spix_api->max_s_pix_num = S_PIX_NUM - (2 - layer_id) * 50;
	p_spix_api->split_th      = S_PIX_TH  - (2 - layer_id) * 20;

	int spix_size = (p_spix_api->img_width * p_spix_api->img_height) / p_spix_api->max_s_pix_num + 1;
	p_spix_api->max_spix_size = (int)((float)(spix_size) * S_PIX_MAX_RATE);  
	p_spix_api->min_spix_size = (int)((float)(spix_size) * S_PIX_MIN_RATE) * (3 - layer_id); 
	
	int linebyte24bit = (width * 3 + 3) / 4 * 4;

	for (y = 0; y < p_spix_api->img_height; y++)
	{
		for (x = 0; x < p_spix_api->img_width; x++)
		{
			index = y * linebyte24bit + x * 3;
			p_spix_api->p_src_img[index + 0] = p_src_img[index + 0];
			p_spix_api->p_src_img[index + 1] = p_src_img[index + 1];
			p_spix_api->p_src_img[index + 2] = p_src_img[index + 2];

			p_spix_api->p_af_map[index + 0]  = p_af_map[index + 0];
			p_spix_api->p_af_map[index + 1]  = p_af_map[index + 1];
			p_spix_api->p_af_map[index + 2]  = p_af_map[index + 2];
		}
	}
}

void copy_src_img_to_debug_img(MSPIX_API* p_spix_api)
{
	int x = 0, y = 0;
	int linebyte24bit = (p_spix_api->img_width * 3 + 3) / 4 * 4;

	for (y = 0; y < p_spix_api->img_height; y++)
	{
		for (x = 0; x < p_spix_api->img_width; x++)
		{
			int index = y * linebyte24bit + x * 3;
			p_spix_api->p_debug_img[index + 0] = p_spix_api->p_src_img[index + 0];
			p_spix_api->p_debug_img[index + 1] = p_spix_api->p_src_img[index + 1];
			p_spix_api->p_debug_img[index + 2] = p_spix_api->p_src_img[index + 2];
		}
	}
}


void greate_label_map(MSPIX_API* p_spix_api, int min_spix_size, int max_spix_size, int threshold)
{
	int				width      = p_spix_api->img_width;
	int				height     = p_spix_api->img_height;
	short*			nlabels    = p_spix_api->p_s_pix_map;//new labels
	//int				K          = p_spix_api->max_s_pix_num; //the number of superpixels desired by the user
	S_Pix*          p_spix     = p_spix_api->p_spix;

	const int dx4[4] = {-1,  0,  1,  0};
	const int dy4[4] = { 0, -1,  0,  1};

	int si = 0;
	const int sz = width*height;

	int label(0);
	int* xvec = new int[sz];
	int* yvec = new int[sz];
	int oindex(0);
	int adjlabel(p_spix_api->max_s_pix_num);//adjacent label

	int min_spix_th = min_spix_size / 2;
	
	int ncolor0 = 0;
	int ncolor1 = 0;
	int ncolor2 = 0;
	int naf     = 0;

	int ocolor0 = 0;
	int ocolor1 = 0;
	int ocolor2 = 0;
	int oaf     = 0;

	int avg_color0 = 0;
	int avg_color1 = 0;
	int avg_color2 = 0;
	int avg_af = 0;

	int color_dis0 = 0;
	int color_dis1 = 0;
	int color_dis2 = 0;
	int af_dis = 0;

	int* olabel = new int [sz];

	for( int i = 0; i < sz; i++ ) 
	{
		olabel[i]  = nlabels[i];
		nlabels[i] = -1;
	}

	for (si = 0; si < p_spix_api->max_s_pix_num; si++)
	{
		p_spix[si].X = 0;
		p_spix[si].Y = 0;
		p_spix[si].size     = 0;
		p_spix[si].color.c0 = 0;
		p_spix[si].color.c1 = 0;
		p_spix[si].color.c2 = 0;
		p_spix[si].color.c3 = 0;
	}

	for( int j = 0; j < height; j+=1 )
	{
		for( int k = 0; k < width; k+=1 )
		{
			oindex = j*width + k;
			if( 0 > nlabels[oindex] )
			{
				nlabels[oindex] = label;

				ocolor0 = p_spix_api->p_src_img[oindex*3 + 0];
				ocolor1 = p_spix_api->p_src_img[oindex*3 + 1];
				ocolor2 = p_spix_api->p_src_img[oindex*3 + 2];
				avg_color0 = ocolor0;
				avg_color1 = ocolor1;
				avg_color2 = ocolor2;

				oaf    = p_spix_api->p_af_map[oindex*3 + 0];
				avg_af = oaf;

				p_spix[label].X = k;
				p_spix[label].Y = j;
				p_spix[label].size = 1;
				p_spix[label].color.c0 = ocolor0;
				p_spix[label].color.c1 = ocolor1;
				p_spix[label].color.c2 = ocolor2;
				p_spix[label].color.c3 = oaf;

				p_spix[label].win[0] = k; //left
				p_spix[label].win[1] = j; //top
				p_spix[label].win[2] = k; //right
				p_spix[label].win[3] = j; //bottom
						
				//--------------------
				// Start a new segment
				//--------------------
				xvec[0] = k;
				yvec[0] = j;

				//-------------------------------------------------------
				// Quickly find an adjacent label for use later if needed
				//-------------------------------------------------------
				adjlabel = p_spix_api->max_s_pix_num;
				int min_dis = 99999999;
				for( int n = 0; n < 4; n++ )
				{
					int x = xvec[0] + dx4[n];
					int y = yvec[0] + dy4[n];
					if( (x >= 0 && x < width) && (y >= 0 && y < height) )
					{
						int nindex = y*width + x;

						if(nlabels[nindex] >= 0 && nlabels[nindex] != adjlabel) 
						{
							ncolor0 = p_spix_api->p_src_img[nindex*3 + 0];
							ncolor1 = p_spix_api->p_src_img[nindex*3 + 1];
							ncolor2 = p_spix_api->p_src_img[nindex*3 + 2];

							color_dis0  = (ocolor0 - ncolor0)*(ocolor0 - ncolor0);
							color_dis1  = (ocolor1 - ncolor1)*(ocolor1 - ncolor1);
							color_dis2  = (ocolor2 - ncolor2)*(ocolor2 - ncolor2);
							int color_dis   = (color_dis0* COLOR_MODIFY_RATE + color_dis1 + color_dis2);

							naf = p_spix_api->p_af_map[nindex*3 + 0];
							int af_dis = (oaf - naf)*(oaf - naf);

							int final_dis = color_dis + af_dis * AFMAP_MODIFY_RATE;

							if (final_dis < min_dis)
							{
								min_dis = final_dis;
								adjlabel = nlabels[nindex];
							}
						}
					}
				}

				int recive_count = 1;
				
				for( int c = 0; c < recive_count; c++ )
				{
					for( int n = 0; n < 4; n++ )
					{
						int x = xvec[c] + dx4[n];
						int y = yvec[c] + dy4[n];

						if( (x >= 0 && x < width) && (y >= 0 && y < height) )
						{
							int nindex = y*width + x;

							if( 0 > nlabels[nindex])
							{
								ncolor0 = p_spix_api->p_src_img[nindex*3 + 0];
								ncolor1 = p_spix_api->p_src_img[nindex*3 + 1];
								ncolor2 = p_spix_api->p_src_img[nindex*3 + 2];

								color_dis0       = (avg_color0 - ncolor0)*(avg_color0 - ncolor0);
								color_dis1       = (avg_color1 - ncolor1)*(avg_color1 - ncolor1);
								color_dis2       = (avg_color2 - ncolor2)*(avg_color2 - ncolor2);
								int an_color_dis = (color_dis0 * COLOR_MODIFY_RATE + color_dis1 + color_dis2);

								naf = p_spix_api->p_af_map[nindex*3 + 0];
								int an_af_dis = (avg_af - naf)*(avg_af - naf);

								int final_dis = an_color_dis + an_af_dis * AFMAP_MODIFY_RATE;

								int dis_th = threshold;
								if(final_dis < dis_th || recive_count < min_spix_th)
								//if(final_dis < dis_th)
								{
									xvec[recive_count]      = x;
									yvec[recive_count]      = y;
									nlabels[nindex]         = label;
									p_spix[label].X        += x;
									p_spix[label].Y        += y;
									p_spix[label].color.c0 += ncolor0;
									p_spix[label].color.c1 += ncolor1;
									p_spix[label].color.c2 += ncolor2;
									p_spix[label].color.c3 += naf;
									p_spix[label].size++;

									avg_color0 = (float)p_spix[label].color.c0 / (float)p_spix[label].size;
									avg_color1 = (float)p_spix[label].color.c1 / (float)p_spix[label].size;
									avg_color2 = (float)p_spix[label].color.c2 / (float)p_spix[label].size;
									avg_af     = (float)p_spix[label].color.c3 / (float)p_spix[label].size;

									if (p_spix[label].win[0] > x)
									{
										p_spix[label].win[0] = x;
									}
									if (p_spix[label].win[2] < x)
									{
										p_spix[label].win[2] = x;
									}
									if (p_spix[label].win[1] > y)
									{
										p_spix[label].win[1] = y;
									}
									if (p_spix[label].win[3] < y)
									{
										p_spix[label].win[3] = y;
									}
									recive_count++;
								}
							}
						}
					}

					int size_th = max_spix_size;
					if(recive_count > size_th)
					{
						break;
					}
				}

				//-------------------------------------------------------
				// If segment size is less then a limit, assign an
				// adjacent label found before, and decrement label count.
				//-------------------------------------------------------
				if(recive_count <= min_spix_size)  //2
				{
					for( int c = 0; c < recive_count; c++ )
					{
						int ind      = yvec[c] * width + xvec[c];
						nlabels[ind] = adjlabel;
					}
					p_spix[adjlabel].X        += p_spix[label].X;   
					p_spix[adjlabel].Y        += p_spix[label].Y;    
					p_spix[adjlabel].size     += p_spix[label].size;
					p_spix[adjlabel].color.c0 += p_spix[label].color.c0;
					p_spix[adjlabel].color.c1 += p_spix[label].color.c1;
					p_spix[adjlabel].color.c2 += p_spix[label].color.c2;
					p_spix[adjlabel].color.c3 += p_spix[label].color.c3;

					if (p_spix[adjlabel].win[0] > p_spix[label].win[0])
					{
						p_spix[adjlabel].win[0] = p_spix[label].win[0];
					}
					if (p_spix[adjlabel].win[2] < p_spix[label].win[2])
					{
						p_spix[adjlabel].win[2] = p_spix[label].win[2];
					}

					if (p_spix[adjlabel].win[1] > p_spix[label].win[1])
					{
						p_spix[adjlabel].win[1] = p_spix[label].win[1];
					}
					if (p_spix[adjlabel].win[3] < p_spix[label].win[3])
					{
						p_spix[adjlabel].win[3] = p_spix[label].win[3];
					}

					label--;
				}
				/*else
				{
					int avg_x = (float)p_spix[label].X / (float)p_spix[label].size;
					int avg_y = (float)p_spix[label].Y / (float)p_spix[label].size;
					int center_label = nlabels[avg_y * width + avg_x];
					if (center_label > 0 && center_label != label)
					{
						for( int c = 0; c < recive_count; c++ )
						{
							int ind      = yvec[c] * width + xvec[c];
							nlabels[ind] = center_label;
						}
						p_spix[center_label].X        += p_spix[label].X;   
						p_spix[center_label].Y        += p_spix[label].Y;    
						p_spix[center_label].size     += p_spix[label].size;
						p_spix[center_label].color.c0 += p_spix[label].color.c0;
						p_spix[center_label].color.c1 += p_spix[label].color.c1;
						p_spix[center_label].color.c2 += p_spix[label].color.c2;
						label--;
					}
				}*/

				label++;

				if (label >= p_spix_api->max_s_pix_num)
				{
					j = height;
					k = width;
				}
			}
			oindex++;
		}
	}

	if (label >= p_spix_api->max_s_pix_num)
	{
		p_spix_api->valid_s_pix_num = p_spix_api->max_s_pix_num;
	}
	else
	{
		p_spix_api->valid_s_pix_num = label;
	}

	for( int i = 0; i < sz; i++ ) 
	{
		if (nlabels[i] < 0)
		{
			nlabels[i] = 0;
		}
	}

	if(xvec)   delete [] xvec;
	if(yvec)   delete [] yvec;
	if(olabel) delete [] olabel;
}


void compute_cs_diff(sp_output* p_sp_out, int img_width, int img_height, int merge_th)
{
	short* p_s_pix_map  = p_sp_out->p_s_pix_map;
	int valid_s_pix_num = p_sp_out->valid_s_pix_num;
	S_Pix* p_sp         = p_sp_out->p_spix;


	for (int center_id = 0; center_id < valid_s_pix_num; center_id++)
	{
		S_Pix* p_center_spix = &p_sp_out->p_spix[center_id];

		int c_color[3] = {p_center_spix->color.c0, p_center_spix->color.c1, p_center_spix->color.c2};
		int neighbor_min_dis = 99999999;
		int neighbor_count = 1;
		p_center_spix->cs_conf = 0;
		for (int si = 0; si < valid_s_pix_num; si++)
		{
			S_Pix* p_surround_spix = &p_sp_out->p_spix[si];
			if (g_neighbor_matrix[center_id][si] > 0)
			{
				int s_color[3] = {p_surround_spix->color.c0, p_surround_spix->color.c1, p_surround_spix->color.c2};
				int channel_0_dis   = (s_color[0] - c_color[0]) * (s_color[0] - c_color[0]); 
				int channel_1_dis   = (s_color[1] - c_color[1]) * (s_color[1] - c_color[1]); 
				int channel_2_dis   = (s_color[2] - c_color[2]) * (s_color[2] - c_color[2]); 
				int all_channel_dis = channel_0_dis * COLOR_MODIFY_RATE + channel_1_dis + channel_2_dis;
				p_center_spix->cs_conf += all_channel_dis;
				neighbor_count++;
			}
		}
		p_center_spix->cs_conf = p_center_spix->cs_conf / (float)neighbor_count;
	}

	int max_dis = -1, min_dis = 9999999;
	for (int si = 0; si < valid_s_pix_num; si++)
	{
		if (max_dis < p_sp[si].cs_conf)
		{
			max_dis = p_sp[si].cs_conf;
		}
		if (min_dis > p_sp[si].cs_conf)
		{
			min_dis = p_sp[si].cs_conf;
		}
	}
	int max_min = max_dis - min_dis;
	if (max_min > 0)
	{
		for (int si = 0; si < valid_s_pix_num; si++)
		{
			p_sp[si].cs_conf = 255.0f * (float)(p_sp_out->p_spix[si].cs_conf - min_dis) / (float)(max_min);
			if (p_sp[si].cs_conf < merge_th)
			{
				p_sp[si].cs_conf = 0;
			}
		}
	}

	//for (int y = 0; y < img_height; y++)
	//{
	//	for (int x = 0; x < img_width; x++)
	//	{
	//		int si = p_sp_out->p_s_pix_map[y * img_width + x];
	//		int index = y * 3 * img_width + x * 3;
	//		g_spix_debug_map[index + 0] = p_sp[si].cs_conf;
	//		g_spix_debug_map[index + 1] = p_sp[si].cs_conf;
	//		g_spix_debug_map[index + 2] = p_sp[si].cs_conf;
	//	}
	//}
}


void merge_spix_by_cs_dis(sp_output* p_sp_out, int img_width, int img_height)
{
	short* p_s_pix_map  = p_sp_out->p_s_pix_map;
	int valid_s_pix_num = p_sp_out->valid_s_pix_num;
	S_Pix* p_sp         = p_sp_out->p_spix;

	for (int center_id = 0; center_id < valid_s_pix_num; center_id++)
	{
		S_Pix* p_center_spix = &p_sp_out->p_spix[center_id];
		p_center_spix->merge_id = center_id;
		if (p_center_spix->cs_conf == 0)
		{
			int c_color[3] = {p_center_spix->color.c0, p_center_spix->color.c1, p_center_spix->color.c2};
			int neighbor_min_dis = 99999999;
			for (int si = 0; si < valid_s_pix_num; si++)
			{
				if (g_neighbor_matrix[center_id][si] > 0)
				{
					S_Pix* p_surround_spix = &p_sp_out->p_spix[si];
					int s_color[3] = {p_surround_spix->color.c0, p_surround_spix->color.c1, p_surround_spix->color.c2};
					int channel_0_dis   = (s_color[0] - c_color[0]) * (s_color[0] - c_color[0]); 
					int channel_1_dis   = (s_color[1] - c_color[1]) * (s_color[1] - c_color[1]); 
					int channel_2_dis   = (s_color[2] - c_color[2]) * (s_color[2] - c_color[2]); 
					int all_channel_dis = channel_0_dis * COLOR_MODIFY_RATE + channel_1_dis + channel_2_dis;
					if (neighbor_min_dis > all_channel_dis && p_surround_spix->cs_conf > 0)
					{
						neighbor_min_dis = all_channel_dis;
						p_center_spix->merge_id = si;
					}
				}
			}
		}
	}

	for (int y = 0; y < img_height; y++)
	{
		for (int x = 0; x < img_width; x++)
		{
			int si = p_sp_out->p_s_pix_map[y * img_width + x];
			p_sp_out->p_s_pix_map[y * img_width + x] = p_sp[si].merge_id;
		}
	}
}

void update_spix(sp_output* p_sp_out, int img_width, int img_height)
{
	S_Pix* p_spix = p_sp_out->p_spix;
	for (int si = 0; si < p_sp_out->valid_s_pix_num; si++)
	{
		p_spix[si].X = 0;
		p_spix[si].Y = 0;
		p_spix[si].size     = 0;
		p_spix[si].color.c0 = 0;
		p_spix[si].color.c1 = 0;
		p_spix[si].color.c2 = 0;
		p_spix[si].win[0] = img_width;
		p_spix[si].win[1] = img_height;
		p_spix[si].win[2] = -1;
		p_spix[si].win[3] = -1;
	}

	for (int y = 0; y < img_height; y++)
	{
		for (int x = 0; x < img_width; x++)
		{
			int index24bit = y * img_width * 3 + 3 * x;
			int si = p_sp_out->p_s_pix_map[y * img_width + x];
			p_spix[si].color.c0 += p_sp_out->p_src_img[index24bit + 0];
			p_spix[si].color.c1 += p_sp_out->p_src_img[index24bit + 1];
			p_spix[si].color.c2 += p_sp_out->p_src_img[index24bit + 2];
			p_spix[si].size++;
			p_spix[si].X += x;
			p_spix[si].Y += y;

			if (p_spix[si].win[0] > x)
			{
				p_spix[si].win[0] = x;
			}
			if (p_spix[si].win[2] < x)
			{
				p_spix[si].win[2] = x;
			}

			if (p_spix[si].win[1] > y)
			{
				p_spix[si].win[1] = y;
			}
			if (p_spix[si].win[3] < y)
			{
				p_spix[si].win[3] = y;
			}
		}
	}


	for (int si = 0; si < p_sp_out->valid_s_pix_num; si++)
	{
		p_sp_out->p_spix[si].is_fg = true;
		p_sp_out->p_spix[si].is_bg = false;
		p_sp_out->p_spix[si].color.c0 = (int)((float)p_sp_out->p_spix[si].color.c0 / (float)p_sp_out->p_spix[si].size + 0.5f);
		p_sp_out->p_spix[si].color.c1 = (int)((float)p_sp_out->p_spix[si].color.c1 / (float)p_sp_out->p_spix[si].size + 0.5f);
		p_sp_out->p_spix[si].color.c2 = (int)((float)p_sp_out->p_spix[si].color.c2 / (float)p_sp_out->p_spix[si].size + 0.5f);
		p_sp_out->p_spix[si].X = (int)((float)p_sp_out->p_spix[si].X / (float)p_sp_out->p_spix[si].size + 0.5f);
		p_sp_out->p_spix[si].Y = (int)((float)p_sp_out->p_spix[si].Y / (float)p_sp_out->p_spix[si].size + 0.5f);
		p_sp_out->p_spix[si].conf         = 0.0f;
		p_sp_out->p_spix[si].vote_count   = 0;
		p_sp_out->p_spix[si].color_conf   = 0.0f;
		p_sp_out->p_spix[si].dis_conf     = 0.0f;
		p_sp_out->p_spix[si].inter_conf   = 0.0f;
		p_sp_out->p_spix[si].size_conf    = 0.0f;
		p_sp_out->p_spix[si].salient_conf = 0.0f;
	}
	for (int wi = 0; wi < 4; wi++)
	{
		p_sp_out->final_win[wi] = 0;
	}

	p_sp_out->is_low_contrast = 0;

}


void create_neighbor_matrix(sp_output* p_sp_out, int img_width, int img_height)
{
	const int dx4[4] = {-1,  0,  1,  0};
	const int dy4[4] = { 0, -1,  0,  1};

	short* p_s_pix_map  = p_sp_out->p_s_pix_map;
	int valid_s_pix_num = p_sp_out->valid_s_pix_num;
	S_Pix* p_sp         = p_sp_out->p_spix;

	for (int n = 0; n < valid_s_pix_num; n++)
	{
		for (int m = 0; m < valid_s_pix_num; m++)
		{
			g_neighbor_matrix[m][n] = 0;
		}
	}

	for( int j = 1; j < img_height - 1; j += 1 )
	{
		for( int k = 1; k < img_width - 1; k += 1 )
		{
			int cur_label = p_s_pix_map[j * img_width + k]; 
			if (cur_label > valid_s_pix_num)
			{
				continue;
			}
			for( int n = 0; n < 4; n++ )
			{
				int x = k + dx4[n];
				int y = j + dy4[n];
				int nei_label = p_s_pix_map[y * img_width + x];
				if (nei_label > valid_s_pix_num)
				{
					break;
				}
				if (nei_label != cur_label)
				{
					g_neighbor_matrix[cur_label][nei_label] = 1;
				}
			}

		}
	}
}


void run_mspix(MSPIX_API* p_spix_api, sp_output* p_sp_out)
{
	//Super Pixel===============
	greate_label_map(p_spix_api, p_spix_api->min_spix_size, p_spix_api->max_spix_size, p_spix_api->split_th); 

	//fill output structure===============
	p_sp_out->p_name             = "MSPIX";
	p_sp_out->avg_superpix_count = 0;
	p_sp_out->p_spix             = p_spix_api->p_spix;
	p_sp_out->p_seg_map          = p_spix_api->p_seg_map;
	p_sp_out->p_src_img          = p_spix_api->p_src_img;
	p_sp_out->p_edge_map         = p_spix_api->p_edge_map;
	p_sp_out->p_s_pix_map        = p_spix_api->p_s_pix_map;
	p_sp_out->p_af_map           = p_spix_api->p_af_map;
	p_sp_out->boundary_ok        = 0;
	p_sp_out->is_low_contrast    = 0;
	p_sp_out->low_con_thres      = 20;

	int si = 0;
	int m, n;
	int count = 0;
	for (si = 0; si < p_spix_api->valid_s_pix_num; si++)
	{
		p_sp_out->p_spix[si].is_fg = true;
		p_sp_out->p_spix[si].is_bg = false;
		p_sp_out->p_spix[si].color.c0 = (int)((float)p_sp_out->p_spix[si].color.c0 / (float)p_sp_out->p_spix[si].size + 0.5f);
		p_sp_out->p_spix[si].color.c1 = (int)((float)p_sp_out->p_spix[si].color.c1 / (float)p_sp_out->p_spix[si].size + 0.5f);
		p_sp_out->p_spix[si].color.c2 = (int)((float)p_sp_out->p_spix[si].color.c2 / (float)p_sp_out->p_spix[si].size + 0.5f);
		p_sp_out->p_spix[si].color.c3 = (int)((float)p_sp_out->p_spix[si].color.c3 / (float)p_sp_out->p_spix[si].size + 0.5f);
		p_sp_out->p_spix[si].X = (int)((float)p_sp_out->p_spix[si].X / (float)p_sp_out->p_spix[si].size + 0.5f);
		p_sp_out->p_spix[si].Y = (int)((float)p_sp_out->p_spix[si].Y / (float)p_sp_out->p_spix[si].size + 0.5f);
		p_sp_out->p_spix[si].conf         = 0.0f;
		p_sp_out->p_spix[si].vote_count   = 0;
		p_sp_out->p_spix[si].color_conf   = 0.0f;
		p_sp_out->p_spix[si].dis_conf     = 0.0f;
		p_sp_out->p_spix[si].inter_conf   = 0.0f;
		p_sp_out->p_spix[si].size_conf    = 0.0f;
		p_sp_out->p_spix[si].salient_conf = 0.0f;
	}
	for (int wi = 0; wi < 4; wi++)
	{
		p_sp_out->final_win[wi] = 0;
	}
	p_sp_out->valid_s_pix_num = p_spix_api->valid_s_pix_num;
	p_sp_out->layer_id = p_spix_api->layer_id;

	create_neighbor_matrix(p_sp_out, p_spix_api->img_width, p_spix_api->img_height);

	//compute_cs_diff(p_sp_out, p_spix_api->img_width, p_spix_api->img_height, 60);  //30
	//merge_spix_by_cs_dis(p_sp_out, p_spix_api->img_width, p_spix_api->img_height);
	//update_spix(p_sp_out, p_spix_api->img_width, p_spix_api->img_height);



}



